# -*- coding: utf-8 -*-
"""
CRM系统自定义异常定义

定义了系统中所有的自定义异常类型，提供统一的错误处理机制。
按照业务模块分类，便于错误定位和处理。
"""

from typing import Optional, Any, Dict


class CRMError(Exception):
    """CRM系统基础异常类"""
    
    def __init__(self, message: str, error_code: Optional[str] = None, details: Optional[Dict[str, Any]] = None):
        super().__init__(message)
        self.message = message
        self.error_code = error_code
        self.details = details or {}
    
    def __str__(self) -> str:
        if self.error_code:
            return f"[{self.error_code}] {self.message}"
        return self.message
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            "error_type": self.__class__.__name__,
            "message": self.message,
            "error_code": self.error_code,
            "details": self.details
        }


# ==================== 数据库相关异常 ====================

class DatabaseError(CRMError):
    """数据库异常基类"""
    pass


class DatabaseConnectionError(DatabaseError):
    """数据库连接异常"""
    def __init__(self, message: str = "数据库连接失败"):
        super().__init__(message, "DB_CONNECTION_ERROR")


class DatabaseTimeoutError(DatabaseError):
    """数据库操作超时异常"""
    def __init__(self, message: str = "数据库操作超时"):
        super().__init__(message, "DB_TIMEOUT_ERROR")


class DatabaseIntegrityError(DatabaseError):
    """数据库完整性异常"""
    def __init__(self, message: str = "数据库完整性约束违反"):
        super().__init__(message, "DB_INTEGRITY_ERROR")


class DatabaseMigrationError(DatabaseError):
    """数据库迁移异常"""
    def __init__(self, message: str = "数据库迁移失败"):
        super().__init__(message, "DB_MIGRATION_ERROR")


# ==================== 数据验证相关异常 ====================

class ValidationError(CRMError):
    """数据验证异常"""
    def __init__(self, message: str, field: Optional[str] = None, value: Optional[Any] = None):
        super().__init__(message, "VALIDATION_ERROR")
        self.field = field
        self.value = value
        if field:
            self.details.update({"field": field, "value": value})


class RequiredFieldError(ValidationError):
    """必填字段缺失异常"""
    def __init__(self, field: str):
        super().__init__(f"必填字段缺失: {field}", "REQUIRED_FIELD_ERROR")
        self.field = field


class InvalidFormatError(ValidationError):
    """格式无效异常"""
    def __init__(self, field: str, value: Any, expected_format: str):
        super().__init__(f"字段 {field} 格式无效: {value}，期望格式: {expected_format}", "INVALID_FORMAT_ERROR")
        self.field = field
        self.value = value
        self.expected_format = expected_format


class ValueOutOfRangeError(ValidationError):
    """值超出范围异常"""
    def __init__(self, field: str, value: Any, min_val: Any = None, max_val: Any = None):
        range_info = ""
        if min_val is not None and max_val is not None:
            range_info = f"，有效范围: {min_val} - {max_val}"
        elif min_val is not None:
            range_info = f"，最小值: {min_val}"
        elif max_val is not None:
            range_info = f"，最大值: {max_val}"
        
        super().__init__(f"字段 {field} 值超出范围: {value}{range_info}", "VALUE_OUT_OF_RANGE_ERROR")
        self.field = field
        self.value = value
        self.min_val = min_val
        self.max_val = max_val


class DuplicateValueError(ValidationError):
    """重复值异常"""
    def __init__(self, field: str, value: Any):
        super().__init__(f"字段 {field} 值重复: {value}", "DUPLICATE_VALUE_ERROR")
        self.field = field
        self.value = value


# ==================== 业务逻辑异常 ====================

class BusinessLogicError(CRMError):
    """业务逻辑异常基类"""
    pass


class BusinessError(BusinessLogicError):
    """业务异常"""
    def __init__(self, message: str, error_code: str = "BUSINESS_ERROR"):
        super().__init__(message, error_code)


class ResourceNotFoundError(BusinessLogicError):
    """资源不存在异常"""
    def __init__(self, resource_type: str, resource_id: Any):
        super().__init__(f"{resource_type} 不存在: {resource_id}", "RESOURCE_NOT_FOUND")
        self.resource_type = resource_type
        self.resource_id = resource_id


class ResourceAlreadyExistsError(BusinessLogicError):
    """资源已存在异常"""
    def __init__(self, resource_type: str, resource_id: Any):
        super().__init__(f"{resource_type} 已存在: {resource_id}", "RESOURCE_ALREADY_EXISTS")
        self.resource_type = resource_type
        self.resource_id = resource_id


class StatusTransitionError(BusinessLogicError):
    """状态转换异常"""
    def __init__(self, current_status: str, target_status: str, reason: str = ""):
        message = f"无法从状态 {current_status} 转换到 {target_status}"
        if reason:
            message += f": {reason}"
        super().__init__(message, "STATUS_TRANSITION_ERROR")
        self.current_status = current_status
        self.target_status = target_status
        self.reason = reason


class InsufficientPermissionError(BusinessLogicError):
    """权限不足异常"""
    def __init__(self, required_permission: str, current_permission: Optional[str] = None):
        message = f"权限不足，需要权限: {required_permission}"
        if current_permission:
            message += f"，当前权限: {current_permission}"
        super().__init__(message, "INSUFFICIENT_PERMISSION")
        self.required_permission = required_permission
        self.current_permission = current_permission


class OperationNotAllowedError(BusinessLogicError):
    """操作不允许异常"""
    def __init__(self, operation: str, reason: str = ""):
        message = f"操作不允许: {operation}"
        if reason:
            message += f"，原因: {reason}"
        super().__init__(message, "OPERATION_NOT_ALLOWED")
        self.operation = operation
        self.reason = reason


# ==================== 客户管理异常 ====================

class CustomerError(BusinessLogicError):
    """客户管理异常基类"""
    pass


class CustomerNotFoundError(CustomerError):
    """客户不存在异常"""
    def __init__(self, customer_id: Any):
        super().__init__(f"客户不存在: {customer_id}", "CUSTOMER_NOT_FOUND")
        self.customer_id = customer_id


class CustomerAlreadyExistsError(CustomerError):
    """客户已存在异常"""
    def __init__(self, identifier: str, value: Any):
        super().__init__(f"客户已存在 ({identifier}): {value}", "CUSTOMER_ALREADY_EXISTS")
        self.identifier = identifier
        self.value = value


class CustomerStatusError(CustomerError):
    """客户状态异常"""
    def __init__(self, customer_id: Any, current_status: str, required_status: str):
        super().__init__(
            f"客户 {customer_id} 当前状态 {current_status} 不符合要求，需要状态: {required_status}",
            "CUSTOMER_STATUS_ERROR"
        )
        self.customer_id = customer_id
        self.current_status = current_status
        self.required_status = required_status


# ==================== 产品管理异常 ====================

class ProductError(BusinessLogicError):
    """产品管理异常基类"""
    pass


class ProductNotFoundError(ProductError):
    """产品不存在异常"""
    def __init__(self, product_id: Any):
        super().__init__(f"产品不存在: {product_id}", "PRODUCT_NOT_FOUND")
        self.product_id = product_id


class ProductUnavailableError(ProductError):
    """产品不可用异常"""
    def __init__(self, product_id: Any, reason: str = ""):
        message = f"产品不可用: {product_id}"
        if reason:
            message += f"，原因: {reason}"
        super().__init__(message, "PRODUCT_UNAVAILABLE")
        self.product_id = product_id
        self.reason = reason


class InsufficientInventoryError(ProductError):
    """库存不足异常"""
    def __init__(self, product_id: Any, requested: int, available: int):
        super().__init__(
            f"产品 {product_id} 库存不足，请求数量: {requested}，可用数量: {available}",
            "INSUFFICIENT_INVENTORY"
        )
        self.product_id = product_id
        self.requested = requested
        self.available = available


# ==================== 活动管理异常 ====================

class ActivityError(BusinessLogicError):
    """活动管理异常基类"""
    pass


class ActivityNotFoundError(ActivityError):
    """活动不存在异常"""
    def __init__(self, activity_id: Any):
        super().__init__(f"活动不存在: {activity_id}", "ACTIVITY_NOT_FOUND")
        self.activity_id = activity_id


class ActivityCapacityExceededError(ActivityError):
    """活动容量超出异常"""
    def __init__(self, activity_id: Any, capacity: int, requested: int):
        super().__init__(
            f"活动 {activity_id} 容量超出，最大容量: {capacity}，请求数量: {requested}",
            "ACTIVITY_CAPACITY_EXCEEDED"
        )
        self.activity_id = activity_id
        self.capacity = capacity
        self.requested = requested


class ActivityRegistrationClosedError(ActivityError):
    """活动报名关闭异常"""
    def __init__(self, activity_id: Any):
        super().__init__(f"活动 {activity_id} 报名已关闭", "ACTIVITY_REGISTRATION_CLOSED")
        self.activity_id = activity_id


# ==================== 销售机会异常 ====================

class OpportunityError(BusinessLogicError):
    """销售机会异常基类"""
    pass


class OpportunityNotFoundError(OpportunityError):
    """销售机会不存在异常"""
    def __init__(self, opportunity_id: Any):
        super().__init__(f"销售机会不存在: {opportunity_id}", "OPPORTUNITY_NOT_FOUND")
        self.opportunity_id = opportunity_id


class OpportunityStageError(OpportunityError):
    """销售机会阶段异常"""
    def __init__(self, opportunity_id: Any, current_stage: str, required_stage: str):
        super().__init__(
            f"销售机会 {opportunity_id} 当前阶段 {current_stage} 不符合要求，需要阶段: {required_stage}",
            "OPPORTUNITY_STAGE_ERROR"
        )
        self.opportunity_id = opportunity_id
        self.current_stage = current_stage
        self.required_stage = required_stage


# ==================== 出团管理异常 ====================

class TourError(BusinessLogicError):
    """出团管理异常基类"""
    pass


class TourNotFoundError(TourError):
    """出团不存在异常"""
    def __init__(self, tour_id: Any):
        super().__init__(f"出团不存在: {tour_id}", "TOUR_NOT_FOUND")
        self.tour_id = tour_id


class TourFullyBookedError(TourError):
    """出团已满异常"""
    def __init__(self, tour_id: Any):
        super().__init__(f"出团 {tour_id} 已满", "TOUR_FULLY_BOOKED")
        self.tour_id = tour_id


class TourBookingClosedError(TourError):
    """出团预订关闭异常"""
    def __init__(self, tour_id: Any):
        super().__init__(f"出团 {tour_id} 预订已关闭", "TOUR_BOOKING_CLOSED")
        self.tour_id = tour_id


# ==================== 服务管理异常 ====================

class ServiceError(BusinessLogicError):
    """服务管理异常基类"""
    pass


class ServiceRecordNotFoundError(ServiceError):
    """服务记录不存在异常"""
    def __init__(self, record_id: Any):
        super().__init__(f"服务记录不存在: {record_id}", "SERVICE_RECORD_NOT_FOUND")
        self.record_id = record_id


class ServiceAlreadyClosedError(ServiceError):
    """服务已关闭异常"""
    def __init__(self, record_id: Any):
        super().__init__(f"服务记录 {record_id} 已关闭", "SERVICE_ALREADY_CLOSED")
        self.record_id = record_id


# ==================== 系统管理异常 ====================

class SystemError(CRMError):
    """系统管理异常基类"""
    pass


class UserNotFoundError(SystemError):
    """用户不存在异常"""
    def __init__(self, user_id: Any):
        super().__init__(f"用户不存在: {user_id}", "USER_NOT_FOUND")
        self.user_id = user_id


class AuthenticationError(SystemError):
    """身份验证异常"""
    def __init__(self, message: str = "身份验证失败"):
        super().__init__(message, "AUTHENTICATION_ERROR")


class AuthorizationError(SystemError):
    """授权异常"""
    def __init__(self, message: str = "授权失败"):
        super().__init__(message, "AUTHORIZATION_ERROR")


class SecurityError(SystemError):
    """安全异常"""
    def __init__(self, message: str = "安全检查失败"):
        super().__init__(message, "SECURITY_ERROR")


class ConfigurationError(SystemError):
    """配置异常"""
    def __init__(self, message: str = "配置错误"):
        super().__init__(message, "CONFIGURATION_ERROR")


class BackupError(SystemError):
    """备份异常"""
    def __init__(self, message: str = "备份操作失败"):
        super().__init__(message, "BACKUP_ERROR")


class RestoreError(SystemError):
    """恢复异常"""
    def __init__(self, message: str = "恢复操作失败"):
        super().__init__(message, "RESTORE_ERROR")


# ==================== 外部服务异常 ====================

class ExternalServiceError(CRMError):
    """外部服务异常基类"""
    pass


class EmailServiceError(ExternalServiceError):
    """邮件服务异常"""
    def __init__(self, message: str = "邮件服务异常"):
        super().__init__(message, "EMAIL_SERVICE_ERROR")


class SMSServiceError(ExternalServiceError):
    """短信服务异常"""
    def __init__(self, message: str = "短信服务异常"):
        super().__init__(message, "SMS_SERVICE_ERROR")


class PaymentServiceError(ExternalServiceError):
    """支付服务异常"""
    def __init__(self, message: str = "支付服务异常"):
        super().__init__(message, "PAYMENT_SERVICE_ERROR")


class FileStorageError(ExternalServiceError):
    """文件存储异常"""
    def __init__(self, message: str = "文件存储异常"):
        super().__init__(message, "FILE_STORAGE_ERROR")


# ==================== 异常处理工具 ====================

class ErrorHandler:
    """错误处理器"""
    
    @staticmethod
    def handle_database_error(error: Exception) -> DatabaseError:
        """处理数据库异常"""
        error_message = str(error)
        
        if "connection" in error_message.lower():
            return DatabaseConnectionError(error_message)
        elif "timeout" in error_message.lower():
            return DatabaseTimeoutError(error_message)
        elif "integrity" in error_message.lower() or "constraint" in error_message.lower():
            return DatabaseIntegrityError(error_message)
        else:
            return DatabaseError(error_message)
    
    @staticmethod
    def handle_validation_error(field: str, value: Any, error_type: str) -> ValidationError:
        """处理验证异常"""
        if error_type == "required":
            return RequiredFieldError(field)
        elif error_type == "format":
            return InvalidFormatError(field, value, "有效格式")
        elif error_type == "duplicate":
            return DuplicateValueError(field, value)
        else:
            return ValidationError(f"字段 {field} 验证失败", field, value)
    
    @staticmethod
    def get_error_info(error: Exception) -> Dict[str, Any]:
        """获取错误信息"""
        if isinstance(error, CRMError):
            return error.to_dict()
        else:
            return {
                "error_type": type(error).__name__,
                "message": str(error),
                "error_code": None,
                "details": {}
            }


# ==================== 异常装饰器 ====================

from functools import wraps
from typing import Callable, TypeVar, Any

T = TypeVar('T')

def handle_exceptions(default_return: Any = None, log_errors: bool = True):
    """异常处理装饰器"""
    def decorator(func: Callable[..., T]) -> Callable[..., T]:
        @wraps(func)
        def wrapper(*args, **kwargs) -> T:
            try:
                return func(*args, **kwargs)
            except CRMError:
                # CRM自定义异常直接抛出
                raise
            except Exception as e:
                if log_errors:
                    import logging
                    logger = logging.getLogger(__name__)
                    logger.error(f"函数 {func.__name__} 发生异常: {e}", exc_info=True)
                
                # 转换为CRM异常
                if "database" in str(e).lower() or "sql" in str(e).lower():
                    raise ErrorHandler.handle_database_error(e)
                else:
                    raise CRMError(f"系统异常: {e}")
        return wrapper
    return decorator


def validate_not_none(param_name: str):
    """非空验证装饰器"""
    def decorator(func: Callable[..., T]) -> Callable[..., T]:
        @wraps(func)
        def wrapper(*args, **kwargs) -> T:
            # 检查参数是否为None
            if param_name in kwargs and kwargs[param_name] is None:
                raise RequiredFieldError(param_name)
            return func(*args, **kwargs)
        return wrapper
    return decorator